For any suggestions or feedback regarding these notes,
please contact Pragy Agarwal
Terms "Master" and "Slave" have a lot of historical baggage - and some communities don't like these words.
Typically in Master-Slave replication, we have an odd number of total servers (replicas). Note: this is NOT mandatory, you can totally have an even number of total “replicas” as well.
Reason: With odd number of server, you have a clear majority.
For example, if X = 3, then you have 1 master + 2 slaves
if X = 5, then you have 1 master + 4 slaves
if X = 2, then you have 1 master + 1 slave
Note: replication factor is the number of copies. It is not the total number of servers. If the database is sharded, we will have shards & replicas. A database can have S=100 shards, each shard having X=3 copies each, for a total of N=300 servers.
Typical values of X = {3, 5}
A re-election will happen. One of the slaves will get elected as the new master.
It will join as a new slave.
Nobody cares. Slaves die all the time.
Basically the read will go to a different slave.
Typically happens via some "distributed configuration management system" (ex. Zookeeper)
But there are other algos as well.
Asynchronously, using Write Ahead Log
Always happen at least in the master.
(in some configurations, the writes can also happen in a subset of the slaves)
In a subset of the slaves
Typically, an even number (so that the total number of servers is odd, because there’s 1 master)
So that we can have a clear majority - easy to do tie breaking (in quorum)
We need at least 2 copies (1 master + 1 slave) — because if we have only 1 copy, there’s no replication in the first place (which will lead to data loss)
Typically we keep 3 copies of data (1 master + 2 slaves)
Sometimes you might need more
Where? | Availability | Latency | |
Reads (R = 1) | at any 1 random slave | Very High | Very Low |
Writes (W = 1) | only at the master | Very High | Very Low |
Note that the writes going to only the master doesn’t mean that slaves don’t have any data. The slaves will periodically sync-up with the master.
Instead, the master contains the latest data always, and the slaves don’t have to latest data always.
Yes.
Writes are happening only at the master. Slaves sync up with master periodically.
If the master goes down (HDD failure) with unsynced changes ⇒ these changes are lost forever!
There can be stale reads because the slaves sync up only periodically.
Note: data loss is even worse than stale reads.
Because this config gives us data loss, we don't even care about stale reads.
we will use this when eventual consistency is good enough
Where? | Availability | Latency | |
Reads (R = 1) | at any 1 random slave | Very High | Very Low |
Writes (W = 2) | Master | Decent | Decent |
By using Two Phase Commit (2PC) — we will acquire distributed locks to ensure that this write to (master + 1 random slave) is atomic. If the write doesn’t succeed at both places, we will return an error to the client and the client can retry (meanwhile we will rollback the partial write)
No. Because the data is in at least 2 places.
What happens if the HDD fails in both the places? That will certainly lead to data loss.
What happens if Thanos attacks earth? Supernova? Black hole? ... if earth explodes, that means data loss.
HDD fails extremely rarely (once every 2-3 years). The chances that these exact two HDDs fail before the rest of the slaves can sync up is astronomically low.
Don't worry about it. It's very rare.
If we still wish to minimize your data losses, then you just write to more places.
Yes. The reads are happening at any 1 random slave, and the slaves are not guaranteed to always have the latest data.
The latest write went to Master + Slave A, but the read went to Slave B, and the Slave B hasn’t been able to sync-up yet —- there will be a stale read.
we will use this when we require immediate consistency, and the writes are rare (read heavy system)
Where? | Availability | Latency | |
Reads | at any 1 random slave | Very High | Very Low |
Writes | all nodes | Very Low | Very High |
Note that the protocol says that we must write to all X nodes. It doesn’t say that you should write to all replicas which are alive.
In write-everywhere, if even 1 replica is down, the writes have to be denied!
In write-everywhere the master's boundary is blurred. There’s basically no diff b/w the master and the slave.
No. All the copies are always in sync, and each write is replicated in multiple places.
No. All copies are always in sync
we will use this when we require immediate consistency, and the writes are frequent (write heavy system or its a balanced system)
Idea: Improve the writes at the cost of reads. In write everywhere, the reads are very fast, but the writes are very slow. If we trade off, then both will be decent.
Where? | Availability | Latency | |
Reads | to a majority | Decent | Decent |
Writes | to a majority (atomically) | Decent | Decent |
Majority = More than half the total amount.
If the Replication Factor = X, then majority will be ceil( (x+1) / 2 )
For example, if your replication factor is X = 5, then any reads or writes must succeed at at-least 3 nodes for the request to be successful.
No. Because we’re writing to a majority, and the majority is at-least 2.
No.
You always read the latest data, because there's at least 1 overlap (there's at least one server that you're reading from that also got the latest write)
Since different reads will return different values, we will always maintain the timestamp whenever writes happen.
And then when reading, we will return the value which has the latest timestamp.
No. The timestamp can be generated at the “coordinator” (the database app server that is coordinating the write across the various replicas)
The replication factor X tells you the minimum number of copies of data you must maintain at all times. You might maintain more copies for whatever reason. Momentarily (when a replica crashes), the number of copies may fall below X. But it is the DBs responsibility to ensure that for most of the time, the number of copies remains at-least X.
What happens if a replica crashes?
Does the replication factor X change? No — the replication factor is a configuration parameter. It is not the live number of replicas.
Irrespective of how many servers have crashed, Quorum requires you to read/write successfully to at-least ceil((x+1)/2) replicas.
For example, if X = 7, so our desired majority is 4. Now imagine that 4 of the servers have crashed. In this case, no reads or writes can happen (because there’s only 3 servers remaining, but Quorum says you need to read/write to at-least 4)
Idea: for immediate consistency, the number of reads & writes don’t have to be equal. All we need to do is ensure that there’s an overlap.
X = Replication Factor — minimum number of copies that must be maintained for each piece of data at all times
R = Number of Reads — minimum number of servers which must respond with data for the read to succeed
W = Number of Writes — minimum number of servers which must acknowledge the write for the write to succeed
same as Master-Slave with no consistency — data loss
write at master, read from any 1 random slave
No consistency, but perfect availability!
same as Master-Slave with eventual consistency
write at master + any 1 random slave, read from any 1 random slave
Eventual consistency, and high availability
we will get eventual consistency
(the number of servers that we're writing to + the number of servers that we're reading from) is more than the total number of available servers.
⇒ there's at least one server that is being both written to and being read from – there's an overlap! (proof: pigeonhole principle)
⇒ we've immediate consistency!
R = 1, W = X ⇒ write everywhere
R = W = (X+1/2) ⇒ quorum
Since we can now choose any values of R+W, this gives us a tremendous amount of power.
If R is low ⇒ reads are faster & more available (because you're reading from only few servers)
If W is low ⇒ writes are faster & more available
If R+W > X ⇒ system is immediately consistent
We can not only decide our consistency, we can also tune the system for read-heavy or write-heavy operation!
In fact, we no longer are limited only to availability or consistency, we can choose any point on the spectrum!
Two Phase Commit (2PC)